As far from land as possible¶
Time: O(MxN); Space: O(MxN); medium
Given an N x N grid containing only values 0 and 1, where 0 represents water and 1 represents land, find a water cell such that its distance to the nearest land cell is maximized and return the distance.
The distance used in this problem is the Manhattan distance: the distance between two cells (x0, y0) and (x1, y1) is |x0 - x1| + |y0 - y1|.
If no land or water exists in the grid, return -1.
Example 1:
Input: grid =
[
[1, 0, 1],
[0, 0, 0],
[1, 0, 1]
]
Output: 2
Explanation:
The cell (1, 1) is as far as possible from all the land with distance 2.
Example 2:
Input: grid =
[
[1, 0, 0],
[0, 0, 0],
[0, 0, 0]
]
Output: 4
Explanation:
The cell (2, 2) is as far as possible from all the land with distance 4.
Notes:
1 <= len(grid) = len(grid[0]) <= 100
grid[i][j] is 0 or 1
[1]:
import collections
class Solution1(object):
"""
Time: O(m * n)
Space: O(m * n)
"""
def maxDistance(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
q = collections.deque([(i, j) for i in range(len(grid))
for j in range(len(grid[0])) if grid[i][j] == 1])
if len(q) == len(grid) * len(grid[0]):
return -1
level = -1
while q:
next_q = collections.deque()
while q:
x, y = q.popleft()
for dx, dy in directions:
nx, ny = x + dx, y + dy
if not (0 <= nx < len(grid) and
0 <= ny < len(grid[0]) and
grid[nx][ny] == 0):
continue
next_q.append((nx, ny))
grid[nx][ny] = 1
q = next_q
level += 1
return level
[2]:
s = Solution1()
grid = [
[1, 0, 1],
[0, 0, 0],
[1, 0, 1]
]
assert s.maxDistance(grid) == 2
grid = [
[1, 0, 0],
[0, 0, 0],
[0, 0, 0]
]
assert s.maxDistance(grid) == 4
[3]:
import collections
class Solution2(object):
def maxDistance(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
queue = collections.deque([])
rows = len(grid)
cols = len(grid[0])
for i in range(rows):
for j in range(cols):
if grid[i][j]:
queue.append((i, j))
if len(queue) == rows * cols or len(queue) == 0:
return -1
while queue:
x, y = queue.popleft()
for i, j in [(x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)]:
if (0 <= i < rows) and (0 <= j < cols):
if grid[i][j] == 0:
grid[i][j] = grid[x][y] + 1
queue.append((i, j))
return max([max(row) for row in grid]) - 1
[4]:
s = Solution2()
grid = [
[1, 0, 1],
[0, 0, 0],
[1, 0, 1]
]
assert s.maxDistance(grid) == 2
grid = [
[1, 0, 0],
[0, 0, 0],
[0, 0, 0]
]
assert s.maxDistance(grid) == 4